

#ifndef _LOG_IMPL_H_
#define _LOG_IMPL_H_

#include <stdio.h>
#include <stdarg.h>
#include <string>

#include "log_defines.h"
#include "thread_queue.h"

using namespace std;

namespace trident
{

class log_impl_t
{
public:

    /**
     * @brief constructor
     */
    log_impl_t();

    /**
     * @brief destructor
     */
    ~log_impl_t();

    /**
     * @brief init the log
     * @return int 0 successful, -1 failed
     */
    int init(const string& file_path_,
        const string& file_name_,
        log_level_e log_level_,
        unsigned long file_max_size_,
        int log_fmt_);

    /**
     * @brief stop log thread and wait for all log flush to disk
     */
	void stop();

    /**
     * @brief log it
     * @param log_level_e log_level_
     * @param const char* fmt_
     * @return int 0 successful, -1 failed
     */
    int doLog(log_level_e log_level_, const char* fmt_, ...);

private:

    /**
     * @brief init file info and eg: file name, size, index and current days
     * @return int 0 successful, -1 failed
     */
    int initFileInfo();

    /**
     * @brief start the log thread
     * @return int 0 successful, -1 failed
     */
    int start();

    /**
     * @brief thread call back function
     * @return NULL
     */
	static void* ThreadProc(void* agrs_);

    /**
     * @brief thread work function
     * @return int 0 successful, -1 failed
     */
	int run();

    /**
     * @brief log and wirte log to file
     * @return int 0 successful, -1 failed
     */
    int doLogInter(const log_queue_data_t& log_queue_data_);

    /**
     * @brief check the file roll condition and whether it need to change the new day or new file
     * @return int 0 successful, -1 failed
     */
    int checkFileRoll();

private:
    log_level_e                                 _log_level;
    int                                         _log_fmt;
    thread_queue_t<log_queue_data_t>            _log_queue;

	pthread_t                                   _pthread_id;
	bool                                        _running;
    unsigned long                               _timeout;

    string                                      _file_path;
    string                                      _file_name;
    string                                      _current_file;
    unsigned long                               _file_max_size;
    FILE*                                       _fp;
    unsigned long                               _current_file_size;
    unsigned int                                _current_file_index;
    unsigned int                                _current_year;
    unsigned int                                _current_month;
    unsigned int                                _current_day;
};

} // namespace trident

#endif //_LOG_IMPL_H_
